#ifndef MSG_NODE_H 
#define MSG_NODE_H 

#include <cstdint>
#include <memory>
#include <cstring>

#include <boost/asio.hpp>

#include "global.h"


using TCP = boost::asio::ip::tcp;

class MsgNode
{
public:
    MsgNode(uint32_t total_len)
    :m_total_len(total_len)
    ,m_cur_len(0)
    ,m_data(new char[total_len + 1]) 
    {
        m_data[m_total_len] = '\0';
    } 

    void Clear()
    {
        m_cur_len = 0;
        memset(m_data.get(), 0, m_total_len);
    }

    uint32_t m_total_len;
    uint32_t m_cur_len;
    std::unique_ptr<char[]> m_data;
};


class HeadNode:public MsgNode
{
public:
    using ptr = std::shared_ptr<HeadNode>;

    HeadNode()
    :MsgNode(HEAD_LENGTH)
    ,m_msg_len(0)
    ,m_msg_id(0)
    {}

    int GetHeatInfo();
    uint32_t GetMsgLen() { return m_msg_len; }
    uint32_t GetMsgId() { return m_msg_id; }
    void Clear()
    {
        MsgNode::Clear();
        m_msg_len = 0;
        m_msg_id = 0;
    }

private:
    uint32_t m_msg_len = 0;
    uint32_t m_msg_id = 0;
};


class RecvNode: public MsgNode
{
public:
    RecvNode(std::shared_ptr<HeadNode> head)
    :MsgNode(head->GetMsgLen())
    ,m_head(head)
    {}

    void Clear()
    {
        MsgNode::Clear();
        m_head->Clear();
    }

    std::shared_ptr<HeadNode> m_head;
};


class SendNode: public MsgNode
{
public:
    SendNode(const char *data, uint32_t len, uint32_t msg_id);

    uint32_t m_msg_id;
};


#endif	/* MSG_NODE_H */
